package com.ruicar.afs.cloud.admin.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.admin.entity.SysPermission;
import com.ruicar.afs.cloud.admin.entity.SysRolePermission;
import com.ruicar.afs.cloud.admin.service.SysPermissionService;
import com.ruicar.afs.cloud.admin.service.SysRolePermissionService;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.holder.TransRequestContextHolder;
import com.ruicar.afs.cloud.common.core.log.annotation.SysLog;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.User;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

import static com.ruicar.afs.cloud.common.core.constant.CommonConstants.BASE_TENANT_ID;
import static com.ruicar.afs.cloud.common.core.constant.CommonConstants.STATUS_NORMAL;


/**
 *
 */
@Slf4j
@RestController
@Api(description = "菜单/权限管理接口")
@RequestMapping("/permission")
@AllArgsConstructor
public class PermissionController {

	private final SysPermissionService sysPermissionService;

	private final SysRolePermissionService sysRolePermissionService;


	@RequestMapping(value = "/getMenuList", method = RequestMethod.GET)
	@ApiOperation(value = "获取用户页面菜单数据")
//	@PreAuthorize("@pms.hasPermission('sys_permission_query')")
	public IResponse<List<SysPermission>> getAllMenuList() {

		List<SysPermission> allUserPermission = null;
		User u = SecurityUtils.getUser();
		//获取用户所有菜单权限
		allUserPermission = sysPermissionService.findByUserId(((AfsUser) u).getId());

		if(allUserPermission==null||allUserPermission.size()==0){
			return IResponse.fail("用户没有配置任何菜单请联系管理员");
		}

		//all button
		List<SysPermission> buttonOrAreaList =  allUserPermission
				.stream()
				.filter(sysPermission ->CommonConstants.PERMISSION_OPERATION.equals(sysPermission.getType())||CommonConstants.PERMISSION_AREA.equals(sysPermission.getType()))
				.collect(Collectors.toList());
		//all menu

		List<SysPermission> menuList = new ArrayList<>();

		allUserPermission.forEach(sysPermission->{
			if(CommonConstants.PERMISSION_PAGE.equals(sysPermission.getType())) {
				menuList.add(sysPermission);
			}
		});

		int level = 1;
		List<SysPermission> permissions = menuList
				.stream()
				.filter(sysPermission -> CommonConstants.PARENT_ID.equals(sysPermission.getParentId()))
				.collect(Collectors.toList());

		permissions.forEach(sysPermission -> {
				findSubPermissionAndButton(sysPermission,menuList,buttonOrAreaList,level,false);
		});

		return new IResponse<List<SysPermission>>().setData(permissions);
	}




	@RequestMapping(value = "/getAllList", method = RequestMethod.GET)
	@ApiOperation(value = "获取权限菜单树")
	@PreAuthorize("@pms.hasPermission('sys_permission_query')")
	public IResponse<List<SysPermission>> getAllList() {

		//all permission
		List<SysPermission> allUserPermission = sysPermissionService
				.list(Wrappers.<SysPermission>lambdaQuery()
						.eq(!BASE_TENANT_ID.equalsIgnoreCase(TransRequestContextHolder.getTenantId()), SysPermission::getTenantHideFlag,STATUS_NORMAL));

		//all button
		List<SysPermission> buttonOrAreaList =  allUserPermission
				.stream()
				.filter(sysPermission ->CommonConstants.PERMISSION_OPERATION.equals(sysPermission.getType())||CommonConstants.PERMISSION_AREA.equals(sysPermission.getType()))
				.collect(Collectors.toList());
		//all menu

		List<SysPermission> menuList = new ArrayList<>();
		allUserPermission.forEach(sysPermission->{
			if(CommonConstants.PERMISSION_PAGE.equals(sysPermission.getType())) {
				menuList.add(sysPermission);
			}
		});
		int level = 1;
		List<SysPermission> permissions = menuList
				.stream()
				.filter(sysPermission -> CommonConstants.PARENT_ID.equals(sysPermission.getParentId()))
				.collect(Collectors.toList());

		permissions.forEach(sysPermission -> {
			findSubPermissionAndButton(sysPermission,menuList,buttonOrAreaList,level,true);
		});

		return new IResponse<List<SysPermission>>().setData(permissions);
	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	@ApiOperation(value = "添加")
	@Transactional
	@SysLog("添加菜单")
	@PreAuthorize("@pms.hasPermission('sys_permission_add')")
	public IResponse<SysPermission> add(@RequestBody SysPermission permission) {

		// 判断拦截请求的操作权限按钮名是否已存在
		if (CommonConstants.PERMISSION_OPERATION.equals(permission.getType())) {
			List<SysPermission> list = sysPermissionService.findByTitle(permission.getTitle());
			if (list != null && list.size() > 0) {
				return new IResponse<SysPermission>().setMsg("名称已存在");
			}
		}
		if(permission.getParentId()==null){
			permission.setParentId(0l);
		}
		sysPermissionService.save(permission);
		//手动删除缓存
		return new IResponse<SysPermission>().setData(permission);
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	@ApiOperation(value = "编辑")
	@Transactional
	@SysLog("编辑菜单")
	@PreAuthorize("@pms.hasPermission('sys_permission_edit')")
	@CacheEvict(value = CommonConstants.USER_CACHE_KEY_PREFIX, allEntries = true)
	public IResponse<SysPermission> edit(@RequestBody SysPermission permission) {

		// 判断拦截请求的操作权限按钮名是否已存在
		if (CommonConstants.PERMISSION_OPERATION.equals(permission.getType())) {
			// 若名称修改
			SysPermission p = sysPermissionService.getById(permission.getId());
			if (!p.getTitle().equals(permission.getTitle())) {
				List<SysPermission> list = sysPermissionService.findByTitle(permission.getTitle());
				if (list != null && list.size() > 0) {
					return new IResponse<SysPermission>().setMsg("名称已存在");
				}
			}
		}
		sysPermissionService.updateById(permission);
		return new IResponse<SysPermission>().setData(permission);
	}

	@RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
	@ApiOperation(value = "批量通过id删除")
	@Transactional
	@SysLog("删除菜单")
	@PreAuthorize("@pms.hasPermission('sys_permission_delete')")
	@CacheEvict(value = CommonConstants.USER_CACHE_KEY_PREFIX, allEntries = true)
	public IResponse<Object> delByIds(@PathVariable Long[] ids) {

		for (Long id : ids) {
			List<SysRolePermission> list = sysRolePermissionService.list(Wrappers
					.<SysRolePermission>query().lambda()
					.eq(SysRolePermission::getRoleId, id));
			if (list != null && list.size() > 0) {
				return new IResponse().setMsg("删除失败，包含正被角色使用关联的菜单或权限");
			}
		}
		sysPermissionService.removeByIds(Arrays.asList(ids));
		return new IResponse().setMsg("批量通过id删除数据成功");
	}

	@RequestMapping(value = "/search", method = RequestMethod.GET)
	@ApiOperation(value = "搜索菜单")
	@PreAuthorize("@pms.hasPermission('sys_permission_query')")
	public IResponse<List<SysPermission>> searchPermissionList(@RequestParam String title) {

		List<SysPermission> list = sysPermissionService.findByTitleLikeOrderBySortOrder(title);
		return new IResponse<List<SysPermission>>().setData(list);
	}

	private void findSubPermissionAndButton(SysPermission permission,List<SysPermission> allPermission,List<SysPermission> buttons,int level,boolean buttonAsChild){


		List<SysPermission> children = allPermission
				.stream()
				.filter(child->permission.getId().equals(child.getParentId()))
				.collect(Collectors.toList());

		List<SysPermission> childrenButtons = buttons
				.stream()
				.filter(button->permission.getId().equals(button.getParentId()))
				.collect(Collectors.toList());

		permission.setPermTypes(
				childrenButtons.stream()
						.filter(button->StringUtils.isNotEmpty(button.getPermissions()))
						.map(button->button.getPermissions().split(","))
						.flatMap(permissions->Arrays.stream(permissions))
						.collect(Collectors.toList())
		);

		if(children.size()==0){
			if(buttonAsChild){
				children.addAll(childrenButtons);
				permission.setChildren(children);
			}
			return;
		}

		if(buttonAsChild){
			children.addAll(childrenButtons);
			permission.setChildren(children);
		}
		children.forEach(child->{
			child.setLevel(level+1);
			findSubPermissionAndButton(child,allPermission,buttons,level+1,buttonAsChild);
		});


		permission.setChildren(children);
	}
}
